[volume-3] 도메인 & 객체 설계 및 아키텍처, 패키지 구성 - 김평숙#89
Closed
katiekim17 wants to merge 44 commits intoLoopers-dev-lab:katiekim17from
Closed
[volume-3] 도메인 & 객체 설계 및 아키텍처, 패키지 구성 - 김평숙#89katiekim17 wants to merge 44 commits intoLoopers-dev-lab:katiekim17from
katiekim17 wants to merge 44 commits intoLoopers-dev-lab:katiekim17from
Conversation
- 회원가입 시퀀스 다이어그램 (핵심 + 예외 플로우) - 내 정보 조회 시퀀스 다이어그램 (헤더 인증 포함) - 비밀번호 변경 시퀀스 다이어그램 (핵심 + 예외 플로우) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
fix : 예제 테스트 코드 오류 해결을 위한 testcontainers 버전 업
Removed the version reference for User entity in requirements.
# Conflicts: # docs/design/브랜드_상품/01-requirements.md # docs/design/좋아요/01-requirements.md
[2주차] 설계 문서 제출 - 김평숙
|
Important Review skippedAuto reviews are disabled on base/target branches other than the default branch. Please check the settings in the CodeRabbit UI or the You can disable this status message by setting the Use the checkbox below for a quick retry:
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
📌 Summary
배경: 이커머스의 핵심 기능(브랜드, 상품, 좋아요, 주문)에 대한 구현이 요구됨.
기존 Member 도메인은 User로의 변경과 VO를 추가해야 했음.
목표: 파사드 패턴을 이용하여 DIP를 이해하고 이에 맞게 개발 진행. 각각의 역할과 책임에 대해 생각해보고 정리한다
결과: 레이어드 아키텍처 기반으로 5개 도메인(User, Brand, Product, Order, Stock)을 구현하고, Domain 레이어에 Repository 인터페이스를 정의 / Infrastructure 레이어에서 구현하는 DIP 구조를 전 도메인에 적용함. Facade가 도메인 서비스를 조합하여 유스케이스를 오케스트레이션하는 패턴을 확립함
🧭 Context & Decision
문제 정의
선택지와 결정
🏗️ Design Overview
변경 범위
주요 컴포넌트 책임
🔁 Flow Diagram
Main Flow - 주문 생성
sequenceDiagram autonumber participant Client participant OrderController participant OrderFacade participant UserService participant ProductService participant OrderService participant StockDeductionService participant DB Client->>OrderController: POST /api/v1/orders OrderController->>OrderFacade: createOrder(loginId, password, items) OrderFacade->>UserService: authenticate(loginId, password) UserService->>DB: findByLoginId + passwordEncoder.matches DB-->>UserService: Users UserService-->>OrderFacade: Users OrderFacade->>ProductService: getProducts(productIds) ProductService->>DB: findAllByIds DB-->>OrderFacade: List<Product> OrderFacade->>ProductService: getBrands(brandIds) ProductService->>DB: findAllByIds DB-->>OrderFacade: List<Brand> OrderFacade->>OrderService: createOrder(userId, products, brandMap, deductionMap) OrderService->>StockDeductionService: deductAll(deductionMap) - sorted by productId StockDeductionService->>DB: findByProductIdWithLock (PESSIMISTIC_WRITE) DB-->>StockDeductionService: Stock (locked) StockDeductionService->>DB: stock.deduct(quantity) OrderService->>DB: save(Order) OrderService->>DB: saveAll(OrderItems + ProductSnapshot) DB-->>OrderService: Order OrderService-->>OrderFacade: Order OrderFacade-->>OrderController: OrderInfo OrderController-->>Client: ApiResponse<OrderInfo>Exception Flow - 주문 생성
sequenceDiagram autonumber participant Client participant OrderController participant OrderFacade participant UserService participant OrderService participant StockDeductionService participant DB Note over Client,DB: Case 1 - 인증 실패 (401) Client->>OrderController: POST /api/v1/orders OrderController->>OrderFacade: createOrder(loginId, password, items) OrderFacade->>UserService: authenticate(loginId, password) UserService->>DB: findByLoginId DB-->>UserService: Users UserService->>UserService: passwordEncoder.matches() == false UserService-->>OrderFacade: CoreException(UNAUTHORIZED) OrderFacade-->>Client: 401 Unauthorized Note over Client,DB: Case 2 - 존재하지 않는 상품 (404) Client->>OrderController: POST /api/v1/orders OrderController->>OrderFacade: createOrder(loginId, password, items) OrderFacade->>UserService: authenticate → OK OrderFacade->>OrderFacade: getProducts(productIds) OrderFacade-->>Client: CoreException(NOT_FOUND) → 404 Note over Client,DB: Case 3 - 재고 부족 (400) Client->>OrderController: POST /api/v1/orders OrderController->>OrderFacade: createOrder(loginId, password, items) OrderFacade->>UserService: authenticate → OK OrderFacade->>OrderService: createOrder(...) OrderService->>StockDeductionService: deductAll(deductionMap) StockDeductionService->>DB: findByProductIdWithLock DB-->>StockDeductionService: Stock (quantity=5) StockDeductionService->>StockDeductionService: stock.deduct(Quantity(99999)) StockDeductionService-->>OrderService: CoreException(BAD_REQUEST, "재고 부족") Note over OrderService,DB: 트랜잭션 롤백 OrderService-->>Client: 400 Bad RequestMain Flow - 브랜드 비활성화 (이벤트 기반 연쇄 처리)
sequenceDiagram autonumber participant Admin participant AdminController participant AdminBrandFacade participant DB participant EventPublisher participant BrandEventListener Admin->>AdminController: DELETE /api-admin/v1/brands/{id} AdminController->>AdminBrandFacade: deactivateBrand(brandId) AdminBrandFacade->>DB: findById(brandId) DB-->>AdminBrandFacade: Brand AdminBrandFacade->>AdminBrandFacade: brand.deactivate() AdminBrandFacade->>DB: save(brand) AdminBrandFacade->>EventPublisher: publish(BrandDeactivatedEvent) AdminBrandFacade-->>AdminController: void AdminController-->>Admin: 204 No Content Note over EventPublisher,BrandEventListener: AFTER_COMMIT + @Async (별도 트랜잭션, REQUIRES_NEW) EventPublisher->>BrandEventListener: handleBrandDeactivated(event) BrandEventListener->>DB: findAllByBrandId(brandId) DB-->>BrandEventListener: List<Product> loop 각 상품 BrandEventListener->>BrandEventListener: product.deactivate() BrandEventListener->>DB: save(product) BrandEventListener->>DB: save(ProductHistory.snapshot(product, version, "system")) endException Flow - 브랜드 비활성화
sequenceDiagram autonumber participant Admin participant AdminController participant AdminBrandFacade participant DB Note over Admin,DB: Case 1 - LDAP 헤더 없음 (403) Admin->>AdminController: DELETE /api-admin/v1/brands/{id} (X-Loopers-Ldap 누락) AdminController->>AdminController: AdminAuthInterceptor 차단 AdminController-->>Admin: 403 Forbidden Note over Admin,DB: Case 2 - 존재하지 않는 브랜드 (404) Admin->>AdminController: DELETE /api-admin/v1/brands/999999 AdminController->>AdminBrandFacade: deactivateBrand(999999) AdminBrandFacade->>DB: findById(999999) DB-->>AdminBrandFacade: Optional.empty() AdminBrandFacade-->>Admin: CoreException(NOT_FOUND) → 404